package main.java.utils.common;

import java.io.*;
import java.util.HashMap;
import java.util.Iterator;
import java.util.Map;
import java.util.function.Function;

public class IOUtil {
	public static void copy(InputStream is, OutputStream os, Progress progress) throws IOException {
		byte[] bytes = new byte[0x1000];
		for (int n = is.read(bytes); n != -1; n = is.read(bytes)) {
			os.write(bytes, 0, n);
			progress.increase(n);
		}
		progress.interrupt();
	}

	public static InputStream inputStream(String resource) {
		return ClassLoader.getSystemResourceAsStream(resource);
	}

	public static Iterable<Map<String, String>> read(InputStream is, Function<String, String[]> separator) {
		Iterable<String> lines = readLines(is);
		Iterator<String> iterator = lines.iterator();
		String[] headers = iterator.hasNext() ? separator.apply(iterator.next()) : null;

		return read(lines, headers, separator);
	}

	public static Iterable<Map<String, String>> read(InputStream is, String[] headers, Function<String, String[]> separator) {
		return read(readLines(is), headers, separator);
	}

	private static Iterable<Map<String, String>> read(Iterable<String> lines, String[] headers, Function<String, String[]> separator) {
		Iterator<String> iterator = lines.iterator();
		return () -> new Iterator<Map<String, String>>() {
			@Override
			public boolean hasNext() {
				return headers != null && iterator.hasNext();
			}

			@Override
			public Map<String, String> next() {
				String[] values = separator.apply(iterator.next());
				Map<String, String> next = new HashMap<>();
				for (int i = 0; i < headers.length; i++) {
					next.put(headers[i], values[i]);
				}
				return next;
			}
		};
	}

	public static Iterable<String> readLines(InputStream is) throws RuntimeException {
		return new BufferedReader(new InputStreamReader(is)).lines()::iterator;
	}
}
